﻿#include <QLineEdit>
#include "DlgBookCity.h"
#include "ui_DlgBookCity.h"
#include "common.h"
#include "MainWindow.h"
#include "ThreadCacheBook.h"

static bool init = false;

DlgBookCity::DlgBookCity(QWidget* parent) :
	DlgCustom(parent),
	ui(new Ui::DlgBookCity),
	m_icon_collection(":/assets/images/collection.png"),
	m_icon_collection_disable(":/assets/images/collection_disable.png")
{
	ui->setupUi(this);
	ui->btnAddWebBook->hide();
	setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);

	QSslConfiguration config = request.sslConfiguration();
	config.setPeerVerifyMode(QSslSocket::VerifyNone);
	config.setProtocol(QSsl::TlsV1SslV3);
	request.setSslConfiguration(config);
	manager = new QNetworkAccessManager(this);
	connect(manager, SIGNAL(finished(QNetworkReply*)),
		this, SLOT(replyFinished(QNetworkReply*)));

	//connect(ui->cbLineEditUrl->lineEdit(), SIGNAL(returnPressed()), this, SLOT(on_btnOpenUrl_clicked()));
	connect(ui->cbLineEditUrl, SIGNAL(on_sig_enter()), this, SLOT(on_btnOpenUrl_clicked()));

	///检查ssl支持，如果版本不够高，需要安装openssl到系统目录
	bool bSupp = QSslSocket::supportsSsl();
	QString buildVersion = QSslSocket::sslLibraryBuildVersionString();
	QString version = QSslSocket::sslLibraryVersionString();
	stringstream ss;
	ss << "supportsSsl:" << bSupp << ", sslLibraryBuildVersion:" << buildVersion.toStdString() << ", sslLibraryVersion:" << version.toStdString() << endl;
	LOG_WRITE(LOG_LEVEL_INFO, ss.str().c_str());
	qDebug() << ss.str().c_str();
	QNetworkAccessManager* accessManager = new QNetworkAccessManager(this);
	qDebug() << accessManager->supportedSchemes();
	if (!bSupp) {
		QString dlgTitle = tr("openssl 版本错误");
		QString strInfo;
		strInfo += "buildVersion: " + buildVersion + "\nversion: " + version + "\nsupportedSchemes:\n";
		for (auto& supportedScheme : accessManager->supportedSchemes()) {
			strInfo += supportedScheme + "\n";
		}
		QMessageBox::critical(this, dlgTitle, strInfo);
	}
}

DlgBookCity::~DlgBookCity()
{
	delete ui;
	delete manager;
}

void DlgBookCity::show()
{
	DlgCustom::show();

	// 窗口显示大小会溢出，必须先显示再设置 ui->cbLineEditUrl 的itemText
	if (init == false) {
		string strText = ThreadCacheBook::get("https://gitee.com/xszbzb/FreeReader/blob/master/readme.txt").data();
		set<string> book_city_default_url;
		auto head = strText.find("web info start");
		if (head != string::npos)
		{
			auto tail = strText.find("web info end");
			if (tail != string::npos)
			{
				auto web_info = strText.substr(head, tail - head);
				size_t index = 0;
				while ((index = web_info.find("&#x000A;", index)) != string::npos)
					web_info.replace(index, 8, "\n");
				string search_prefix = "search_prefix_url=";
				head = web_info.find(search_prefix) + search_prefix.length();
				m_search_prefix_url = web_info.substr(head, web_info.find("\n", head) - head);
				string book_city_default = "book_city_default_url=";
				while ((head = web_info.find(book_city_default, head)) != string::npos)
				{
					head += book_city_default.length();
					tail = web_info.find("\n", head);
					book_city_default_url.insert(web_info.substr(head, tail - head));
					head = tail;
				}
			}
		}
		if (m_search_prefix_url.empty())
			m_search_prefix_url = "https://www.12xs.top/book/";
		if (book_city_default_url.empty())
			book_city_default_url.insert("https://www.biqugeu.net/");

		// 读收藏数据添加到下拉列表
		int size = g_set->beginReadArray("book_city/CollectionUrl");
		int i = 0;
		for (; i < size; ++i) {
			g_set->setArrayIndex(i);
			QString url = g_set->value("url").toString();
			if (-1 == ui->cbLineEditUrl->findText(url))
				ui->cbLineEditUrl->addItem(url);
		}
		g_set->endArray();
		for (auto& url : book_city_default_url)
		{
			if (ui->cbLineEditUrl->findText(url.c_str()) == -1)
				ui->cbLineEditUrl->addItem(url.c_str());
		}

		//这个一定要放在最后才加载上次关闭时记录的url，上面addItem时会导致刷新ui->cbLineEditUrl->currentText
		m_strUrlHistory.push_back(g_set->value(tr("book_city/url"), (*book_city_default_url.begin()).c_str()).toString());
		ui->cbLineEditUrl->setCurrentText(m_strUrlHistory[0]);
		init = true;
	}

	on_btnOpenUrl_clicked();
}

void DlgBookCity::on_btnAddWebBook_clicked()
{
	MainWindow* mw = ((MainWindow*)parent());
	QString strUrl = ui->cbLineEditUrl->currentText();
	if (ui->btnAddWebBook->text() == "移出书架")
	{
		mw->DelBook(strUrl);
		ui->btnAddWebBook->setText("加入书架");
	}
	else
	{
		sBookInfo book("", strUrl);
		book.utf8 = m_utf8;
		string str = m_strText.toStdString();
		GetWebBookInfo(str, book);

	GET_WEB_INFO:
		int iRet = ThreadCacheBook::GetWebBookImage(book, str);
		if (iRet != 0)
		{
			QMessageBox::StandardButton btnSelect;
			btnSelect = QMessageBox::warning(this, tr("警告"), book.name
				+ tr("\n获取网书图片失败!是否重试?"), QMessageBox::Yes | QMessageBox::No);
			if (btnSelect == QMessageBox::Yes)
			{
				goto GET_WEB_INFO;
			}
		}

		vector<BookChapterList> chapterList;
		ThreadCacheBook::GetChapterListToFile(book, chapterList, str);
		mw->AddBookInfoToWeiget(book, 0);
		SaveBookListInfo();
		ui->btnAddWebBook->setText("移出书架");
		return;
	}
}

void DlgBookCity::on_btnOpenUrl_clicked()
{
	QString strUrl = ui->cbLineEditUrl->currentText();
	//static QString strUrlOld;
	//if (strUrl == strUrlOld)
	//	return;
	//strUrlOld = strUrl;
	if (strUrl.indexOf('.') != -1)
	{
		getUrlText(strUrl);
	}
	else if (strUrl.indexOf("、") == -1)
	{
		on_btnSearchWebBook_clicked();
	}
}

void DlgBookCity::replyFinished(QNetworkReply* reply)
{
	//if (isVisible())
	{
		QString strUrl = reply->url().toString();
		ui->cbLineEditUrl->setCurrentText(strUrl);
		if (m_strUrlHistory.back() != strUrl)
		{
			m_strUrlHistory.push_back(strUrl);
			if (m_strUrlHistory.size() > 10)
				m_strUrlHistory.pop_front();
		}

		int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
		QVariant redirectAttr = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
		if (reply->error())
			//|| 300 == statusCode //状态码300 Multiple Choices，既不是错误也不算重定向，应该是qt bug
			//|| !redirectAttr.isNull())
		{
			qDebug() << reply->errorString();
			m_strText = CurrentDate().c_str();
			m_strText += "\nERROR: statusCode ";
			m_strText += reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toString() + "\n";
			m_strText += redirectAttr.toString();
			m_strText += "\n";
			m_strText += reply->errorString();
			ui->textBrowser->setText(m_strText);
			reply->deleteLater();
			return;
		}

		// <2>检测网页返回状态码，常见是200，404等，200为成功
		//int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
		qDebug() << "statusCode:" << statusCode;
		// <3>判断是否需要重定向
		if (statusCode >= 300 && statusCode < 400) {
			// redirect
			// 获取重定向信息
			const QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
			// 检测是否需要重定向，如果不需要则读数据
			if (!redirectionTarget.isNull()) {
				const QUrl redirectedUrl = reply->url().resolved(redirectionTarget.toUrl());
				reply->deleteLater();
				reply = nullptr;
				getUrlText(redirectedUrl.toString());
				qDebug() << "http redirect to " << redirectedUrl.toString();
				return;
			}
		}
		string str = reply->readAll().data();
		string strCharset = GetCharset(str);
		if (strCharset == "utf-8")
		{
			m_utf8 = true;
			m_strText = QString::fromStdString(str.c_str());
		}
		else
		{
			m_utf8 = false;
			m_strText = ToUnicode(str.c_str(), strCharset.c_str());
			//m_strText = ANSIToUTF8(str.c_str()).data();
		}

		if (m_strText.isEmpty())
		{
			qDebug() << reply->errorString();
			m_strText = CurrentDate().c_str();
			m_strText += "\nERROR: statusCode ";
			m_strText += reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toString() + "\n";
			m_strText += redirectAttr.toString();
			m_strText += "\n";
			m_strText += reply->errorString();
			ui->textBrowser->setText(m_strText);
			reply->deleteLater();
			return;
		}

		g_set->setValue("book_city/url", strUrl);
		if ((m_strText.indexOf(tr("《")) != -1 && m_strText.indexOf(tr("》")) != -1) ||
			m_strText.indexOf(tr(":book_name")) != -1) //og:novel:book_name
		{
			bool exist = false;
			for (auto& book : m_listBookInfo)
			{
				if (book.path.size() == strUrl.size() && book.path == strUrl)
				{
					exist = true;
					break;
				}
			}
			exist ? ui->btnAddWebBook->setText("移出书架") : ui->btnAddWebBook->setText("加入书架");
			ui->btnAddWebBook->show();
		}
		else
		{
			ui->btnAddWebBook->hide();
		}
		if (m_strText.size() < 100)
		{
			auto index = m_strText.indexOf("<script>");
			if (index != -1) {
				m_strText.replace(QRegularExpression(".*\"(.*)\".*"), "\\1");
			}
		}
		ui->textBrowser->setText(m_strText);
	}
	reply->deleteLater();
}

void DlgBookCity::on_textBrowser_anchorClicked(const QUrl& arg1)
{
	QString strUrlTail = arg1.toString();
	QString strUrl = ui->cbLineEditUrl->currentText();
	strUrlTail = getUrlFullPath(strUrl, strUrlTail);
	getUrlText(strUrlTail);
}

void DlgBookCity::on_btnBackspace_clicked()
{
	if (m_strUrlHistory.size() > 1)
	{
		m_strUrlHistory.pop_back();
		ui->cbLineEditUrl->setCurrentText(m_strUrlHistory.back());
		getUrlText(m_strUrlHistory.back());
	}
}

void DlgBookCity::getUrlText(QString strUrl)
{
	//m_strText.clear();
	auto url = QUrl(strUrl);
	//for (auto& book : m_listBookInfo)
	//{
	//	if (book.path.indexOf(url.host()) != -1 && !book.utf8)
	//	{
	//		url.setQuery(url.query(), QUrl::DecodedMode);
	//		break;
	//	}
	//}
	request.setUrl(url);
	manager->get(request);
}

void DlgBookCity::on_cbLineEditUrl_currentIndexChanged(const QString&)
{
	if (init)
		on_btnOpenUrl_clicked();
}

void DlgBookCity::on_btnSearchWebBook_clicked()
{
	QString strUrl(m_search_prefix_url.c_str());
	strUrl += ui->cbLineEditUrl->currentText();
	getUrlText(strUrl);
}

void DlgBookCity::on_btnCollectionUrl_clicked()
{
	QString strUrl = ui->cbLineEditUrl->currentText();
	//if (strUrl.indexOf("http") == -1)
	//	return;
	m_isCollectionUpdate = true;
	// 检查是否已经收藏本网页地址
	int index = 0;
	if (-1 != (index = ui->cbLineEditUrl->findText(strUrl)))
	{
		ui->btnCollectionUrl->setIcon(m_icon_collection_disable);
		ui->cbLineEditUrl->removeItem(index);
	}
	else
	{
		ui->btnCollectionUrl->setIcon(m_icon_collection);
		ui->cbLineEditUrl->addItem(strUrl);
	}
}

void DlgBookCity::reject()
{
	if (m_isCollectionUpdate == true)
	{
		m_isCollectionUpdate = false;
		// 写收藏网址到配置文件
		g_set->beginWriteArray("book_city/CollectionUrl");
		int i = 0;
		for (; i < ui->cbLineEditUrl->count(); ++i) {
			g_set->setArrayIndex(i);
			g_set->setValue("url", ui->cbLineEditUrl->itemText(i));
		}
		g_set->endArray();
	}

	DlgCustom::reject();
}

void DlgBookCity::on_cbLineEditUrl_currentTextChanged(const QString& strUrl)
{
	// 检查是否已经收藏本网页地址
	if (-1 == ui->cbLineEditUrl->findText(strUrl))
		ui->btnCollectionUrl->setIcon(m_icon_collection_disable);
	else
		ui->btnCollectionUrl->setIcon(m_icon_collection);
}
